package cn.iocoder.yudao.module.shop.service.price;

import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.framework.security.core.LoginUser;
import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
import cn.iocoder.yudao.module.shop.convert.priceitem.ShopPriceItemConvert;
import cn.iocoder.yudao.module.shop.dal.dataobject.priceitem.ShopPriceItemDO;
import cn.iocoder.yudao.module.shop.service.priceitem.ShopPriceItemService;
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;

import java.util.*;
import cn.iocoder.yudao.module.shop.controller.admin.price.vo.*;
import cn.iocoder.yudao.module.shop.dal.dataobject.price.ShopPriceDO;
import cn.iocoder.yudao.framework.common.pojo.PageResult;

import cn.iocoder.yudao.module.shop.convert.price.ShopPriceConvert;
import cn.iocoder.yudao.module.shop.dal.mysql.price.ShopPriceMapper;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.module.shop.enums.ErrorCodeConstants.*;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.ListUtil;

/**
 * 店内价格套餐 Service 实现类
 *
 * @author 曹建伟
 */
@Service
@Validated
public class ShopPriceServiceImpl implements ShopPriceService {

    @Resource
    private ShopPriceMapper priceMapper;

    @Resource
    private ShopPriceItemService shopPriceItemService;

    @Resource
    private AdminUserApi adminUserApi;

    @Override
    public Long createPrice(ShopPriceCreateReqVO createReqVO) {
        List<Long> itemIdList = createReqVO.getItemIdList();
        List<Integer> priceList = createReqVO.getPriceList();

        if(itemIdList.size() != priceList.size()){
            throw exception(ITEM_PRICE_NOT_EQUAL);
        }

        // 客户端发来 单位是 元
        for(int i = 0; i<priceList.size(); i++){
            priceList.set(i, priceList.get(i) * 100);
        }

        // 插入
        ShopPriceDO price = ShopPriceConvert.INSTANCE.convert(createReqVO.getName(), createReqVO.getTenantId());
        priceMapper.insert(price);

        shopPriceItemService.createPriceItemBatch(ShopPriceConvert.INSTANCE.convertPriceItem(price.getId(), itemIdList, priceList, createReqVO.getTenantId()));
        // 返回
        return price.getId();
    }

    @Override
    public void updatePrice(ShopPriceUpdateReqVO updateReqVO) {
        // 校验存在
        validatePriceExists(updateReqVO.getId());

        if(updateReqVO.getItemIdList().size() != updateReqVO.getPriceList().size()){
            throw exception(ITEM_PRICE_NOT_EQUAL);
        }

        // 更新
        ShopPriceDO updateObj = ShopPriceConvert.INSTANCE.convert(updateReqVO);
        priceMapper.updateById(updateObj);

        if(updateReqVO.getItemIdList().size() == 0 ){
            return;
        }

        for(int i = 0; i<updateReqVO.getItemIdList().size(); i++){
            Long itemId = updateReqVO.getItemIdList().get(i);
            Integer price = updateReqVO.getPriceList().get(i) * 100;

            ShopPriceItemDO  shopPriceItemDO = shopPriceItemService.getPriceItem(updateReqVO.getId(), itemId);
            if(shopPriceItemDO == null){
                shopPriceItemService.createPriceItem(ShopPriceItemConvert.INSTANCE.convertCreate(updateReqVO.getId(), itemId, price, updateReqVO.getTenantId()));
            }else {
                shopPriceItemService.updatePriceItem(ShopPriceItemConvert.INSTANCE.convertUpdate(shopPriceItemDO.getId(), updateReqVO.getId(), itemId, price));
            }
        }
    }

    @Override
    public void deletePrice(Long id) {
        // 校验存在
        validatePriceExists(id);
        // 删除
        priceMapper.deleteById(id);
    }

    private void validatePriceExists(Long id) {
        if (priceMapper.selectById(id) == null) {
            throw exception(PRICE_NOT_EXISTS);
        }
    }

    @Override
    public ShopPriceDO getPrice(Long id) {
        return priceMapper.selectById(id);
    }

    @Override
    public List<ShopPriceDO> getPriceList(Collection<Long> ids) {
        if (CollUtil.isEmpty(ids)) {
            return ListUtil.empty();
        }
        return priceMapper.selectBatchIds(ids);
    }

    @Override
    public PageResult<ShopPriceDO> getPricePage(ShopPricePageReqVO pageReqVO) {
        return priceMapper.selectPage(pageReqVO);
    }

    @Override
    public List<ShopPriceDO> getPriceList(ShopPriceExportReqVO exportReqVO) {
        return priceMapper.selectList(exportReqVO);
    }

    @Override
    public ShopPriceDO getDefaultPrice(){
        LoginUser loginUser = SecurityFrameworkUtils.getLoginUser();
        if(loginUser == null){
            return null;
        }

        AdminUserRespDTO user = adminUserApi.getUser(loginUser.getId());
        if(user == null){
            return null;
        }

        List<ShopPriceDO> list = priceMapper.selectList(new LambdaQueryWrapperX<ShopPriceDO>()
                .eq(ShopPriceDO::getTenantId, user.getTenantId()));

        for(int i = 0; i<list.size(); i++){
            if(list.get(i).getIsDefault()){
                return list.get(i);
            }
        }

        if(list.size() == 0){
            return null;
        }

        return list.get(0);
    }

    @Override
    public Boolean changeDefault(Long priceId, Long tenantId){
        List<ShopPriceDO> list = priceMapper.selectList(new LambdaQueryWrapperX<ShopPriceDO>()
                .eq(ShopPriceDO::getTenantId, tenantId));

        ShopPriceDO currentDefault = null;
        ShopPriceDO targetDefault = null;
        for(int i = 0; i<list.size(); i++){
            if(list.get(i).getIsDefault()){
                currentDefault = list.get(i);
            }

            if(list.get(i).getId().equals(priceId)){
                targetDefault = list.get(i);
            }
        }

        if(currentDefault != null){
            currentDefault.setIsDefault(false);
            priceMapper.updateById(currentDefault);
        }

        if(targetDefault != null){
            targetDefault.setIsDefault(true);
            priceMapper.updateById(targetDefault);
        }

        return true;


    }

}
